% coding: utf-8

\section{Desarrollo}


\subsection{Primera parte: port scanning.}
\begin{itemize}
\item \textit{Implementar SYN scan y Connect scan utilizando lo explicado en clase.}
\subitem \underline{SYN scan}

En primer lugar, armamos un paquete TCP con el flag S activado para iniciar una conexi\'on con (IP, puerto) pasado como par\'ametro y lo enviamos. Tenemos tres respuestas posibles: Puerto abierto, cerrado, o filtrado. Para el primer caso contamos con una variable ``puerto$\_$abierto'' seteada en 18, ya que este n\'umero representa los flags SYN y ACK del header TCP activados. Para comparar esta variable con las flags de la respuesta que recibimos del env\'io del paquete anterior para ver si el puerto en cuesti\'on est\'a abierto hacemos un and l\'ogico. De manera an\'aloga, para ver si el puerto est\'a cerrado, utilizamos la variable ``puerto$\_$cerrado'' seteada en el n\'umero 4. Este valor representa el flag RST activado. Por \'ultimo, para el caso en el que no se recibe ninguna respuesta durante cierto tiempo, se asume el puerto filtrado. 

En la clase correspondiente a este taller, se mencion\'o el hecho de que se podr\'ia recibir una respuesta de tipo ICMP indicando \textit{destination unreachable} para el caso en que el puerto est\'e filtrado. Intentamos obtener este resultado y no lo logramos. Por este motivo utilizamos Wireshark para ver el tr\'afico en la red y corroborar que no estuviera llegando tal paquete. Efectivamente nunca llega un paquete de tipo ICMP, por lo que asumimos que si ocurre un timeout, el puerto est\'a filtrado.

\begin{Verbatim}[frame=single, label=C\'odigo, numbers=left]
from scapy.all import *

def syn_scan(ip, puerto, interfaz='eth0'):
    src_mac = get_if_hwaddr(interfaz)
    dst_mac = getmacbyip(ip) 
    dst_ip  = ip

    puerto_cerrado = 4
    puerto_abierto = 18

    paquete = (
        Ether(
            src=src_mac,
            dst=dst_mac
        )/IP(
            dst=dst_ip
        )/TCP(
            sport=RandShort(),
            dport=puerto,
            flags='S',
            seq=RandShort()
        )
    )
    respuesta = srp1(paquete,timeout=15)  
    resultado = 'Filtrado'
    if respuesta: 
        print respuesta.getlayer(TCP).flags
        if (respuesta.getlayer(TCP).flags
        	& puerto_cerrado == puerto_cerrado):
	        resultado = "Cerrado"
        if (respuesta.getlayer(TCP).flags
        	& puerto_abierto == puerto_abierto):
	        resultado = "Abierto"
    return resultado
\end{Verbatim}

\subitem \underline{Connect scan}

     	Para este tipo de scan, usamos la primitiva \textbf{connect} de \textbf{socket}. Lo que hacemos es intentar establecer una conexi\'on con esta primitiva, salvando el error con una estructura ``try$-$except''. Si puede conectarse asumimos que el puerto est\'a abierto, y sino no podemos asegurar nada (puede estar cerrado o filtrado).

\begin{Verbatim}[frame=single, label=C\'odigo, numbers=left]
import socket

def connect_scan(ip, puerto):
    s = socket.socket()
    s.settimeout(15)
    try:
        s.connect((ip,puerto)) 
        # si se puede conectar entonces asumo que esta abierto
        resultado = "Abierto"
        s.close()
    except :
        resultado = "Cerrado o Filtrado" 
        # si no se puede conectar, lo unico que sabe es que el puerto 
        # es inalcanzable. Por lo que no puede determinar si es 
        # filtrado o cerrado
    return resultado
\end{Verbatim}

\item \textit{?`Cu\'al es la complejidad algor\'itmica de estos m\'etodos? Comparar tiempo contra cantidad de operaciones.}

      Para medir el tiempo que demora cada funci\'on, lo que hicimos fueron dos funciones en las que se realizan 20 ejecuciones de la funci\'on, guardando la hora anterior y posterior a tal ejecuci\'on, sumando a un total la diferencia de estos valores en cada iteración. Luego se calcula el promedio de las 20 iteraciones.

\begin{Verbatim}[frame=single, label=C\'odigo, numbers=left]
import time

def medir_tiempo_syn_scan(ip, puerto):
    total = 0
    for i in range(0,20):
        start = time.time()
        syn_scan(ip, puerto)
        end = time.time()
        total = total + end - start
    return total/20

def medir_tiempo_connect_scan(ip, puerto):
    total = 0
    for i in range(0,20):
        start = time.time()
        connect_scan(ip, puerto)
        end = time.time()
        total = total + end - start
    return total/20
\end{Verbatim}
	
      En promedio vimos que connect$\_$scan demora menos en obtener una respuesta que syn$\_$scan. Sin embargo, en la complejidad algor\'itmica en cantidad de operaciones de cada uno, ocurre lo inverso (teniendo en cuenta s\'olo el establecimiento de dicha conexi\'on $-$ 3$-$way handshake ). Para el primer caso son tres operaciones y para el segundo dos. Esto nos llam\'o la atenci\'on, y a pesar de que investigamos cu\'al pod\'ia ser el motivo no encontramos nada en concreto. Consideramos que la diferencia puede deberse al hecho de que en el caso de syn scan armamos los paquetes paso a paso, y connect scan es una primitiva ya hecha que se ocupa de todo el handshake, por lo que creemos que puede tener alg\'un tipo de optimizaci\'on en la implementaci\'on.

      A continuaci\'on mostramos dos ejemplos de los tiempos promedios obtenidos, para un puerto cerrado y un puerto abierto en el host con IP 192.168.1.101, tanto para syn$\_$scan como para connect$\_$scan
	
\begin{center}
\begin{tabular}{|l |l |l |l|} \hline
\camposcolorS{Puerto}{Estado}{Tiempo syn}{Tiempo connect}
\hline
\filapar{80}{Close}{0.16774029731750489}{0.0028800725936889648}
\hline
\filapar{445}{Open}{0.17969880104064942}{0.0033541679382324218}
\hline
\end{tabular}
\end{center}

% el puerto 80 de esta ip esta cerrado
% ej1.medir_tiempo_syn_scan('192.168.1.101',80)
% 0.16774029731750489

% ej1.medir_tiempo_connect_scan('192.168.1.101',80)
% 0.0028800725936889648

% con puerto abierto
% ej1.medir_tiempo_connect_scan('192.168.1.101',445)
% 0.0033541679382324218

%ej1.medir_tiempo_syn_scan('192.168.1.101',445)
%0.17969880104064942


\item \textit{Discutir sobre cu\'an inocuos resultan estos m\'etodos.}

     	Dado que syn$\_$scan nunca crea una sesi\'on de TCP, los intentos de detecci\'on de los puertos nunca se loguean en las aplicaciones de los hosts destinos, por lo que este m\'etodo tiene poca visibilidad del lado del destino ya que nunca se inicializan sesiones. Adem\'as, por este mismo motivo este m\'etodo es poco invasivo para las aplicaciones en los puertos que se intentan scannear ya que no se reservan recursos.

     	En el caso de connect$\_$scan, ocurre todo lo contrario ya que se completa el 3$-$way$-$handshake por lo que se loguea en el destino y se reservan recursos, teniendo esto gran visibilidad y sobrecarga en las aplicaciones de los puertos que se est\'an scanneando. 

\item \textit{?`Es posible tomar conciencia de que una detecci\'on de puertos est\'a siendo realizada?}

     	Por lo que explicamos en la pregunta anterior, en el caso de connect$\_$scan es m\'as sencillo descubrir una detecci\'on de puertos ya que en cada caso se crea una conexi\'on y este evento puede ser registrado del lado del destino. En el caso de syn$\_$scan, dado que no se establece por completo la conexi\'on, no se loguear\'a tal evento en el lado del destino. 

     	Por otro lado, si existiera un sistema de detecci\'on de intrusos, este tipo de scanneo podr\'ia ser detectado a\'un con m\'as importancia que connect$\_$scan ya que para el primero es necesario tener m\'as permisos, y si se registran los intentos de establecimiento de conexi\'on fallidos por falta de permisos, esto podr\'ia generar m\'as ruido a\'un que el hecho de ver conexiones establecidas. Si un administrador est\'a observando los paquetes en la red en wireshark, podr\'ia detectar los paquetes de tipo syn teniendo un mayor control sobre los mismos, y hacer un an\'alisis mas exhaustivo del tr\'afico en su red.

\item \textit{?`En qu\'e escenarios son efectivos? ?`En cu\'ales carecen de utilidad?}

     	Syn$\_$scan es efectivo en la mayoria de los casos ya que se puede diferenciar el estado real de los puertos. No as\'i con connect$\_$scan que s\'olo se puede diferenciar abierto o no abierto. Tambi\'en vale la pena aclarar que no sabemos como afecta al resultado el hecho de tener un firewall de windows en el medio.
	Dado que connect$\_$scan utiliza primitivas de la API del sistema operativo es posible utilizarlo en situaciones donde no se poseen los permisos para ejecutar syn$\_$scan.

\item \textit{Considerar el siguiente escenario: se desconoce la existencia de un firewall intermedio. ?`Qu\'e se podr\'ia determinar con esta t\'ecnica?}

     	Podr\'ia ocurrir que al hacer el scanneo obtengamos un falso negativo, ya que es posible que el puerto est\'e abierto, pero debido a la existencia de un firewall intermedio termine siendo filtrado y lo veamos como un puerto cerrado.

\end{itemize}

